/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_BLUETOOTH_DFE_CONFIG_H_
#define ZEPHYR_INCLUDE_BLUETOOTH_DFE_CONFIG_H_

#if defined(CONFIG_BT_CTLR_DF_SUBSYSTEM)

/** @brief Maxkimum number of 8[us] periods that may be set as DFE duration */
#define DFE_MAX_8US_PERIODS (20)
/** @brief Minimum number of 8[us] periods that may be set as DFE duration */
#define DFE_MIN_8US_PERIODS (2)

/** @brief Sets DFE mode.
 *
 * There are two kinds of DFE: angle of arrival, angle of departure.
 *
 * @note The only one mode that is supported by Bluetooth Link Layer is
 * 	 angle of arrival. The function allows to set angle of departure also
 * 	 but that configuration has no effect.
 *
 * @param[in] mode		One of following values: @ref RADIO_DFEMODE_DFEOPMODE_AoA,
 * 			@ref RADIO_DFEMODE_DFEOPMODE_AoD
 *
 * @retval 0		If mode set correctly
 * @retval -EINVAL	Unsupported argument value
 */
int dfe_set_mode(u8_t mode);

/** @brief Sets DFE duration.
 *
 * The function sets duration of DFE. Real value of duration in time units is evaluated
 * by the provided numb_of_8us_periods multiplied by 8[us].
 * Minimum DFE duration is @ref DFE_MIN_8US_PERIODS.
 * Maximum DFE duration is @ref DFE_MAX_8US_PERIODS.
 *
 * @note Currently supported maximum number of 8[us] periods is 10. It is caused
 * by an issue that is investigated. Keep in mind that usage of values higher
 * than 10 may end with no I/Q samples provided.
 *
 * Pay attention that DFE duration for broadcaster should be longer or equal
 * duration expected by receiver.
 *
 * @param[in] numb_of_8us_periods Duration of DFE in number of 8us periods
 *
 * @retval 0		If duration was set correctly
 * @retval -EINVAL	Unsupported argument value
 */
int dfe_set_duration(u8_t numb_of_8us_periods);

/** @brief Sets DFE start point.
 *
 * DFE may be started to broadcast/receive CTE during packet payload or at
 * the end of CRC.
 *
 * @note The setting does not have any effect when DFE is started with task only
 * 	 setting enabled @see dfe_set_trig_dfe_start_task_only.
 *
 * @note Currently CTE may be added to the end of CRC.
 *
 * Pay attention that DFE start point must set to the same point for broadcaster
 * and receiver.
 *
 * @param[in] start_point	One of following values: @ref RADIO_DFECTRL1_DFEINEXTENSION_Payload,
 * 			@ref RADIO_DFECTRL1_DFEINEXTENSION_CRC
 *
 * @retval 0		If duration was set correctly
 * @retval -EINVAL	Unsupported argument value
 */
int dfe_set_start_point(u8_t start_point);

#if defined(CONFIG_BT_CTLR_DFE_RX)

/** @brief Enables sampling of CTE when CRC error occurs.
 *
 * Samples by default are gathered only when CRC of a received packet is correct.
 * In case of error, samples are not gathered. It is possible to take and store
 * samples even in case when CRC is wrong.
 *
 * @param[in] value	true to enable sampling when CRC error, false otherwise
 */
void dfe_set_sample_on_crc_error(bool value);

/** @brief Enables DFE to be started only by tasks.
 *
 * If the setting is enabled then DFE procedure will be started by TASKS_DFESTART
 * only. In such case setting provided by @see dfe_set_start_point has no effect.
 *
 * @param[in] value		true to enable starting DFE with task, false otherwise
 */
void dfe_set_trig_dfe_start_task_only(bool value);

/** @brief Sets sample spacing in reference period.
 *
 * There are allowed following values to be set by the function:
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_4us 4us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_2us 2us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_1us 1us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_500ns 0.5us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_250ns 0.25us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACINGREF_125ns 0.125us
 * Pay attention that spacing 1us is only Bluetooth comply setting value.
 * Other values are Nordic radio extensions.
 *
 * @param[in] spacing	Spacing provided by one of values mentioned above.
 *
 * @retval 0		Spacing was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_sampling_spacing_ref(u8_t spacing);

/** @brief Sets sampling type.
 *
 * Sampling type is a kind of data structure used by radio to provide samples:
 * - @ref RADIO_DFECTRL1_SAMPLETYPE_IQ
 * - @ref RADIO_DFECTRL1_SAMPLETYPE_MagPhase
 *
 * @param[in] type	Type of samples to be provided.
 *
 * @retval 0		Sampling type was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_sampling_type(u8_t type);

/** @brief Sets sample spacing in antenna switching period.
 *
 * There are allowed following values to be set by the function:
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_4us 4us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_2us 2us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_1us 1us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_500ns 0.5us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_250ns 0.25us
 *  - @ref RADIO_DFECTRL1_TSAMPLESPACING_125ns 0.125us
 * Pay attention that spacing 1us and 2us are only Bluetooth comply setting values.
 * Other values are Nordic radio extensions.
 *
 * @param[in] spacing	Spacing provided by one of values mentioned above.
 *
 * @retval 0		Spacing was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_sample_spacing(u8_t spacing);

/** @brief Maximum number of steps that may be set to backoff gain on CTE start */
#define DFE_MAX_BACKOFF_STEPS (0xF)

/** @brief Sets number of steps the gain should be backoff when start of CTE.
 *
 * Maximum number of steps that gain may be backoff is @ref DFE_MAX_BACKOFF_STEPS.
 * By default there is no backoff gain (value set to 0).
 *
 * @param[in] value		Number of steps to backoff gain
 *
 * @retval 0		Backoff value was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_backoff_gain(u8_t value);

/** @brief Minimum value that may be set as switch antenna offset.
 *
 * The offset value is a number of 16M cycles (62.5[ns]). The provided value
 * is signed.
 */
#define DFE_SWITCH_OFFSET_MAX (0x1FFF)

/** @brief Maximum value that may be set as switch antenna offset.
 *
 * The offset value is a number of 16M cycles (62.5[ns]). The provided value
 * is signed.
 */
#define DFE_SWITCH_OFFSET_MIN (-DFE_SWITCH_OFFSET_MAX - 1)

/** @brief Sets offset value after end of CRC before starting antenna switching.
 *
 * The setting allows to do some fine tuning of antenna switching start point.
 * The delay is added before start of guard period (switch from idle antenna
 * to first one, reference antenna).
 *
 * Minimum possible value is @ref DFE_SWITCH_OFFSET_MIN, maximum possible
 * value is @ref DFE_SWITCH_OFFSET_MAX.
 *
 * @param[in] value		Number between: @ref DFE_SWITCH_OFFSET_MIN, @ref DFE_SWITCH_OFFSET_MAX
 *
 * @retval 0		Switch offset value was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_switch_offset(u8_t offset);

/** @brief Sets antenna switch spacing.
 *
 * There are allowed following values to be set by the function:
 *  - @ref RADIO_DFECTRL1_TSWITCHSPACING_4us 4us
 *  - @ref RADIO_DFECTRL1_TSWITCHSPACING_2us 2us
 *  - @ref RADIO_DFECTRL1_TSWITCHSPACING_1us 1us
 * Pay attention that spacing 2us and 4us are only Bluetooth comply setting values.
 * 1[us] switch spacing in Nordic radio extension.
 *
 * @param[in] spacing	Spacing provided by one of values mentioned above.
 *
 * @retval 0		Spacing was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_ant_switch_spacing(u8_t spacing);

/** @brief Minimum value that may be set as sample offset.
 *
 * The offset value is a number of 16M cycles (62.5[ns]). The provided value
 * is signed.
 */
#define DFE_SAMPLE_OFFSET_MAX (0x1FFF)

/** @brief Maximum value that may be set as sample offset.
 *
 * The offset value is a number of 16M cycles (62.5[ns]). The provided value
 * is signed.
 */
#define DFE_SAMPLE_OFFSET_MIN (-DFE_SAMPLE_OFFSET_MAX - 1)

/** @brief Sets offset value after end of guard period before starting sampling.
 *
 * The setting allows to do some fine tuning of start point of sampling. The
 * delay is added before first sample in reference period.
 *
 * Minimum possible value is @ref DFE_SAMPLE_OFFSET_MIN, maximum possible
 * value is @ref DFE_SAMPLE_OFFSET_MAX.
 *
 * @param[in] value		Number between: @ref DFE_SAMPLE_OFFSET_MIN, @ref DFE_SAMPLE_OFFSET_MAX
 *
 * @retval 0		Sample offset value was set correctly.
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_sample_offset(u8_t offset);

/** @brief Maximum number of GPIOs that may be used for antennas switching */
#define DFE_ANT_GPIO_MAX 8

/** @brief Antenna switching GPIO structure
 */
struct dfe_ant_gpio {
	/** @brief index of the DFE slot where to place the GPIO
	 */
	u8_t idx;
	/** @brief GPIO descriptor that consists of port and GPIO number.
	 * This is a 6 bit value: 0-4 bits are GPIO number, 5th bit is
	 * post number [0,1].
	 */
	u8_t gpio_num;
};

/** @brief Sets GPIOs that may be used by radio to process antenna switching.
 *
 * There is up to 8 possible slots to set GPIOS to be used for antenna switching.
 * Each GPIO is a "single bit" to be used to address (enable/disable) particular
 * antenna.
 * GPIOs are provided as array. The length of the array must be in range [1-8].
 *
 * @param[in] gpip		Pointer to array of GPIOs
 * @param[in] len		Length of the array
 *
 * @retval 0		GPIOs were set successfully
 * @retval -EINVAL	Unsupported argument value
 */
int dfe_set_ant_gpios(const struct dfe_ant_gpio *gpio, u8_t len);

/** @brief Sets GPIO patterns to enable particular antennas during DFE.
 *
 * Patterns are applied during antenna switching.
 * Each pattern is applied as binary value to GPIOS configured by dfe_set_ant_gpios.
 * So each bit of pattern is mapped to a GPIO.
 * There is up to 40 antenna patterns that may be configured.
 * The minimum required number of patterns is 3: idle pattern,
 * guard + reference periods, switching period.

 * @param[in] idle		Pattern to be used in idle state
 * @param[in] ref		Pattern to be used in guard + reference period
 * @param[in] switching	Array of patterns to be used in switching period
 * @param[in] switching_len	Number of patterns in @p switching array. Max possible
 * 			is 38 (40 - 2 for idle and reference).
 *
 * @retval 0		Patterns were set successfully
 * @retval -EINVAL	Unsupported argument value.
 */
int dfe_set_ant_gpio_patterns(u8_t idle, u8_t ref, u8_t *switching, u8_t switching_len);

#endif /* CONFIG_BT_CTLR_DFE_RX */

#endif /* CONFIG_BT_CTLR_DF_SUBSYSTEM */

#endif /* ZEPHYR_KERNEL_INCLUDE_BLUETOOTH_DFE_CONFIG_H_ */
